package response

import (
	"fmt"
	"gitee.com/zackeus/go-boot/freeswitch/esl/headers"
	"net/textproto"
	"net/url"
	"strings"
)

const (
	TypeEventPlain    = `text/event-plain`
	TypeEventJSON     = `text/event-json`
	TypeEventXML      = `text/event-xml`
	TypeRudeRejection = `text/rude-rejection`
	TypeReply         = `command/reply`
	TypeAPIResponse   = `api/response`
	TypeAuthRequest   = `auth/request`
	TypeDisconnect    = `text/disconnect-notice`

	ResReloadOk = `Reload XML [Success]`
)

// RawResponse 包含来自 FreeSWITCH 的所有响应数据
type RawResponse struct {
	Headers textproto.MIMEHeader
	Body    []byte
}

// ChannelUUID Helper to get the channel UUID. Calls GetHeader internally
func (r RawResponse) ChannelUUID() string {
	return r.GetHeader(headers.UniqueID)
}

// HasHeader Helper to check if the RawResponse has a header
func (r RawResponse) HasHeader(header string) bool {
	_, ok := r.Headers[textproto.CanonicalMIMEHeaderKey(header)]
	return ok
}

// GetHeader Helper function that calls RawResponse.Headers.Get. Result gets passed through url.PathUnescape
func (r RawResponse) GetHeader(header string) string {
	value, _ := url.PathUnescape(r.Headers.Get(header))
	return value
}

// GetReply Helper to get the Reply text from FreeSWITCH, uses the Reply-Text header primarily.
// Also will use the body if the Reply-Text header does not exist, this can be the case for TypeAPIResponse
func (r RawResponse) GetReply() string {
	if r.HasHeader(headers.ReplyText) {
		return r.GetHeader(headers.ReplyText)
	}
	return string(r.Body)
}

// GetVariable Helper function to get "Variable_" headers. Calls GetHeader internally
func (r RawResponse) GetVariable(variable string) string {
	return r.GetHeader(fmt.Sprintf("Variable_%s", variable))
}

// IsOk Helper to check response status, uses the Reply-Text header primarily. Calls GetReply internally
func (r RawResponse) IsOk() bool {
	return strings.HasPrefix(r.GetReply(), "+OK")
}

// String Implement the Stringer interface for pretty printing
func (r RawResponse) String() string {
	var builder strings.Builder
	for key, values := range r.Headers {
		builder.WriteString(fmt.Sprintf("%s: %#v\n", key, values))
	}
	builder.Write(r.Body)
	return builder.String()
}

// GoString Implement the GoStringer interface for pretty printing (%#v)
func (r RawResponse) GoString() string {
	return r.String()
}
